#!/bin/bash
#
#	License: (MIT) <https://mit-license.org/>
#
#	Copyright (c) 2020-2022 Leonid Gasheev aka <https://github.com/The-going>
#
#	mkdir -p ~/tmp/kernel.org-5.10/patches.kernel.org
#	cd /gituser/linux-stable>
#	mk_format_patch . v5.10.40..v5.10.41 ~/tmp/kernel.org-5.10/patches.kernel.org
#

used_f ()
{
	echo -e "$mess"
	echo -e "\n    Used:"
	echo -e "\n$0 <LOCAL GIT URL> <tag..tag> <patches.name dir>\n\nor"
	echo -e "\n$0 <LOCAL GIT URL> <tag..tag> <patches.name dir> <prefix=PREF> <numbered=true>\n"
}

# intelect copy
# Copy only those patches that have changed their content,
# so as not to create unnecessary noise.
ii_cp()
{
	local new_p=$1
	local old_p=$2

	# Patches can be extracted in several ways.
	# Copy only those patches that have changes in chunks,
	# line numbers, or source text.
	# Ignore lines that may be changed by another method
	# of extracting (creating) the patch.
	if [ "$(diff -N \
		--ignore-matching-lines="^From [0-9a-f]\{40\}" \
		--ignore-matching-lines="^index [0-9a-f]\{7\}" \
		--ignore-matching-lines="^Subject:" \
		--ignore-matching-lines='/.*/* |[ ][ 1-9]' \
		--ignore-matching-lines='^Armbian$' \
		--ignore-matching-lines="^[2-3].[1-9][0-9]" \
		$old_p $new_p 2>/dev/null)" != "" ]
	then
		cp --backup=none -f $new_p $old_p
		counter=1
	else
		counter=0
	fi
}

mk_patch_series ()
{
	local url_t="${1}"
	if test -d "$url_t"; then url_t="$(realpath $url_t)"; fi
	local range="${2:-HEAD..HEAD}"
	local target="${3:-~/tmp}"
	if test -d $target; then target="$(realpath $target)"; fi
	for p in ${4} ${5} ${6}
	do
		case $p in
			*=*) eval "local ${p}" ;;
		esac
	done

	local target_name
	local target_dir
	local mess=""
	numbered=${numbered:-false}

	echo -e "\nLOCAL GIT URL =: [\033[1;34m$url_t\033[0m]"
	echo -e "revision range =: [\033[1;34m$range\033[0m]"
	echo -e "target folder for patches =: [\033[1;34m$target\033[0m]"
	echo -e "prefix =: [\033[1;34m$prefix\033[0m]"
	echo -e "numbered =: [\033[1;31m${numbered}\033[0m]\n"

	[ -d $url_t ] || mess+="  bad url [$url_t]\n"
	git -C $url_t rev-parse --git-dir 2>/dev/null || mess+="  It's NOT git\n"

	[ $(git -C $url_t rev-list ${range%..*} -1 2>/dev/null) ] || \
	mess+="  bad first tag [${range%..*}]\n"

	[ $(git -C $url_t rev-list ${range#*..} -1 2>/dev/null) ] || \
	mess+="  bad second tag [${range#*..}]\n"

	[ -d $target ] || mess+="  bad target dir [$target]\n"

if [ "$mess" == "" ]
then
	local tmp_dir=$(mktemp -d /tmp/format_patch_XXXXXXX)
	local origin_url="$(git -C $url_t remote get-url origin 2>/dev/null)"

	echo "    It's generate format-patch: "
	echo "    In tmp folder: $tmp_dir"

	target_name="$(basename $target)"
	target_dir="$(dirname $target)"

	if ! $numbered
	then
		numbered=false
		if test "${target_name#*.}" != "$target_name"
		then
			sufix="${target_name#*.}"
		else
			sufix="conf"
		fi
	else
		case "$origin_url" in

		*linux-stable*)
			numbered=${numbered:-true}
			prefix="${range#*..v}-"
			sufix="kernel.org"
			;;

		*megous*)
			numbered=${numbered:-false}
			t_branch="$(git -C $url_t branch --show-current)"
			prefix=${prefix:-"o${t_branch#*-}-"}
			#sufix="${t_branch%%-*}${t_branch#*-}"
			sufix="megous"
			;;

		*linux-evl*)
			numbered=${numbered:-false}
			t_branch="$(git -C $url_t branch --show-current)"
			sufix='evl'
			;;

		*)
			numbered=${numbered:-true}
			prefix=PREF
			sufix=SUF
			;;
		esac

	fi


	if [ -f ${target_dir}/series.$sufix ];then

		mv -f ${target_dir}/series.$sufix	${target_dir}/series.${sufix}.old
		grep "^#.*$" ${target_dir}/series.${sufix}.old > ${target_dir}/series.$sufix

	else

		echo -e "#\n#\tAutomatically generated by the script mk_format_patch\n#" \
			>${target_dir}/series.$sufix

		[ -n "$origin_url" ] && \
		echo -e "#\t${origin_url}\n#" >>${target_dir}/series.$sufix

	fi

	if $numbered
	then
		$(git -C $url_t \
			format-patch $range \
			-o $tmp_dir/
		) 2>/dev/null

		echo -e "\t\tAll generated patches: [$(ls $tmp_dir | wc -l)]"
		$(cd $tmp_dir
			for pt in $(git -C $url_t log --graph --no-merges --pretty=%H $range | awk '{print $2}' | tac | xargs -I {} grep -l {} *)
			do
				if test -s $pt
				then
					echo -e "\t$target_name/${prefix}${pt#*0}" \
						>> ${target_dir}/series.$sufix

					mv $pt ${target}/${prefix}${pt#*0}
				fi
			done
		)

	else
		mkdir $tmp_dir/$target_name
		sum_counter=0
		prefix=""

		$(git -C $url_t \
			format-patch --filename-max-length=75 --abbrev=12 $range \
			-o $tmp_dir/$target_name
		) 2>/dev/null

		echo -e "\t\tAll generated patches: [$(cd $tmp_dir/$target_name; ls | wc -l)]"
		$(cd $tmp_dir/$target_name
			for pt in $(git -C $url_t log --graph --no-merges --pretty=%H $range | awk '{print $2}' | tac | xargs -I {} grep -l {} *)
			do
				if test -s $pt
				then
					if test -f ${prefix}${pt#*-} && test -f "2-${prefix}${pt#*-}";then

						$(konsole -e /usr/bin/nano "2-${prefix}${pt#*-}") & \
						konsole -e /usr/bin/nano ${pt} & \
						konsole -e /usr/bin/nano ../series.$sufix && \
						wait

					elif test -f ${prefix}${pt#*-};then

						echo -e "\t$target_name/2-${prefix}${pt#*-}" \
							>> ../series.$sufix
						mv $pt "2-${prefix}${pt#*-}"

					else
						echo -e "\t$target_name/${prefix}${pt#*-}" \
							>> ../series.$sufix
						mv $pt ${prefix}${pt#*-}
					fi
				else
					rm $pt
				fi
			done
		)
		echo -e "\t\tGood patches: [$(cd $tmp_dir/$target_name; ls | wc -l)]"

		# Remove non-existent patches if they have been renamed or are no longer applied.
		$(cd $target
			for pt in ./*.patch
			do
				if test ! -f $tmp_dir/$target_name/$pt;then rm $pt;fi
			done
		)

		# Intelligent copying
		$(cd $tmp_dir/$target_name
			for pt in ./*.patch
			do
				ii_cp $pt $target/$pt
			done
		)
		cat $tmp_dir/series.$sufix >>${target_dir}/series.$sufix
		rm -f ${target_dir}/series.${sufix}.old

	fi

	rm -rf $tmp_dir
else
	used_f
fi
}

########## start ##########
counter=0
#echo "cmd line = [$@]"
mk_patch_series ${1} ${2} ${3} ${4} ${5} ${6}

###########
exit
###########
